using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using SoinusLibrary.Data;
using SoinusLibrary.Log;
using System.Collections.Generic;

/// <summary>
/// Summary description for SoinusDBManager
/// </summary>
/// 

public class SoinusDBM : DBManager
{
    #region Singleton
    private static SoinusDBM instance;
    public static SoinusDBM Instance
    {
        get
        {
            if (instance == null) instance = new SoinusDBM();
            return instance;
        }
    } 
    #endregion

    #region Constructor
    private SoinusDBM()
        : base(ConfigurationManager.ConnectionStrings["dbConnectionString"].ConnectionString)
    {
    }
    
    #endregion

    #region Methods
    internal bool Authenticate(string email, string password)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        this.Connect();

        cmd = new SqlCommand("Authenticate", this.con);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
        cmd.Parameters.Add("@password", SqlDbType.NVarChar).Value = password;
        rowsAffected = (Int32)cmd.ExecuteScalar();
        cmd.Dispose();

        this.Disconnect();

        if (rowsAffected == 1)
            return true;
        else return false;
    }

    internal bool DeleteFile(Guid guid, string folder, string file, string email)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("DeleteFile", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@guid", SqlDbType.UniqueIdentifier).Value = guid;
            cmd.Parameters.Add("@folder", SqlDbType.NVarChar).Value = folder;
            cmd.Parameters.Add("@file", SqlDbType.NVarChar).Value = file;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@rowsAffected", SqlDbType.Int).Value = 0;
            cmd.Parameters["@rowsAffected"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            rowsAffected = (Int32)cmd.Parameters["@rowsAffected"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        if (rowsAffected == 1)
            return true;
        else return false;
    }
    
    internal bool DeleteFolder(Guid guid, string folder, string email)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("DeleteFolder", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@guid", SqlDbType.UniqueIdentifier).Value = guid;
            cmd.Parameters.Add("@folder", SqlDbType.NVarChar).Value = folder;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@rowsAffected", SqlDbType.Int).Value = 0;
            cmd.Parameters["@rowsAffected"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            rowsAffected = (Int32)cmd.Parameters["@rowsAffected"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        if (rowsAffected == 1)
            return true;
        else return false;
    }

    internal bool DeletePC(Guid guid, string email)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("DeletePC", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@guid", SqlDbType.UniqueIdentifier).Value = guid;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@rowsAffected", SqlDbType.Int).Value = 0;
            cmd.Parameters["@rowsAffected"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            rowsAffected = (Int32)cmd.Parameters["@rowsAffected"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        if (rowsAffected == 1)
            return true;
        else return false;
    }

    internal Guid GetUserGUID(string email)
    {
        Guid userGuid = Guid.Empty;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("GetUserGUID", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@guid", SqlDbType.UniqueIdentifier).Value = userGuid;
            cmd.Parameters["@guid"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            userGuid = (Guid)cmd.Parameters["@guid"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        return userGuid;
    }

    internal List<StoredFileInfo> GetUserFiles(string email)
    {
        SqlCommand cmd = null;
        List<StoredFileInfo> result = new List<StoredFileInfo>();
        
        try
        {
            this.Connect();

            cmd = new SqlCommand("GetUserFiles", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            using (SqlDataReader sqlDataReader = cmd.ExecuteReader())
            {
                if (sqlDataReader.HasRows)
                {
                    while (sqlDataReader.Read())
                    {
                        string name = sqlDataReader[0] as string;
                        string folder = sqlDataReader[1] as string;
                        string ip = sqlDataReader[2] as string;
                        result.Add(new StoredFileInfo(name, folder, ip));
                    }
                }
            }
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        return result;
    }

    internal bool RegisterFile(Guid guid, string folder, string file, string email)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("RegisterFile", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@guid", SqlDbType.UniqueIdentifier).Value = guid;
            cmd.Parameters.Add("@folder", SqlDbType.NVarChar).Value = folder;
            cmd.Parameters.Add("@file", SqlDbType.NVarChar).Value = file;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@rowsAffected", SqlDbType.Int).Value = 0;
            cmd.Parameters["@rowsAffected"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            rowsAffected = (Int32)cmd.Parameters["@rowsAffected"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        if (rowsAffected == 1)
            return true;
        else return false;
    }

    internal bool RegisterFolder(Guid guid, string folder, string email)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("RegisterFolder", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@guid", SqlDbType.UniqueIdentifier).Value = guid;
            cmd.Parameters.Add("@folder", SqlDbType.NVarChar).Value = folder;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@rowsAffected", SqlDbType.Int).Value = 0;
            cmd.Parameters["@rowsAffected"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            rowsAffected = (Int32)cmd.Parameters["@rowsAffected"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        if (rowsAffected == 1)
            return true;
        else return false;
    }

    internal bool RegisterPC(Guid guid, string email, string ip)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("RegisterPC", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@guid", SqlDbType.UniqueIdentifier).Value = guid;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@ip", SqlDbType.NVarChar).Value = ip;
            cmd.Parameters.Add("@rowsAffected", SqlDbType.Int).Value = 0;
            cmd.Parameters["@rowsAffected"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            rowsAffected = (Int32)cmd.Parameters["@rowsAffected"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        if (rowsAffected == 1)
            return true;
        else return false;
    }

    internal bool RegisterUser(string email, string password)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        try
        {
            this.Connect();

            cmd = new SqlCommand("RegistryUser", this.con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
            cmd.Parameters.Add("@password", SqlDbType.NVarChar).Value = password;
            cmd.Parameters.Add("@rowsAffected", SqlDbType.Int).Value = 0;
            cmd.Parameters["@rowsAffected"].Direction = ParameterDirection.Output;
            cmd.ExecuteNonQuery();
            rowsAffected = (Int32)cmd.Parameters["@rowsAffected"].Value;
            cmd.Dispose();

            this.Disconnect();
        }
        catch (SqlException ex)
        {
            try
            {
                LogManager.Instance.WriteLog(new LogEntry(ex.Source, ex.Message));
            }
            catch (Exception exLog)
            {
                System.Console.WriteLine("%1 %2", exLog.StackTrace, exLog.Message);
            }
        }

        if (rowsAffected == 1)
            return true;
        else return false;
    }

    internal bool UserExists(string email)
    {
        Int32 rowsAffected = -1;
        SqlCommand cmd = null;

        this.Connect();

        cmd = new SqlCommand("UserExists", this.con);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email;
        rowsAffected = (Int32)cmd.ExecuteScalar();
        cmd.Dispose();

        this.Disconnect();

        if (rowsAffected == 1)
            return true;
        else return false;
    } 
    #endregion
}

